package com.tbit.main.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.tbit.main.constant.*;
import com.tbit.main.dao.core.MachineFeeBoundDao;
import com.tbit.main.h2.pojo.ParkPoint;
import com.tbit.main.pojo.*;
import com.tbit.main.remote.rpc.UQHttpClient;
import com.tbit.main.remote.rpc.UQHttpManager;
import com.tbit.main.remote.sms.XCSmsClient;
import com.tbit.main.service.*;
import com.tbit.main.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("quartzJobService")
public class QuartzJobServiceImpl implements QuartzJobService {
    @Autowired
    private TerBatteryService terBatteryService;
    @Autowired
    private TerPositionService terPositionService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private MachineBorrowService machineBorrowService;
    @Autowired
    private MachineAbnormalService machineAbnormalService;
    @Autowired
    private TerControlService terControlService;
    @Autowired
    private ParkPointService parkPointService;
    @Autowired
    private MachineAttrService machineAttrService;
    @Autowired
    private ParkService parkService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private MachineStatusService machineStatusService;
    @Autowired
    private PowerChangeLogService powerChangeLogService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RideLogService rideLogService;
    @Autowired
    private OrderLogService orderLogService;
    @Autowired
    private AccountFeeService accountFeeService;
    @Autowired
    private ProhibitAreaService prohibitAreaService;
    @Autowired
    private MachineOccupyService machineOccupyService;
    @Autowired
    private MQProducer mqProducer;
    @Autowired
    private UserService userService;
    @Autowired
    private SmsAuthConfigService smsAuthConfigService;
    @Autowired
    private DataService dataService;
    @Autowired
    private WorkOrderService workOrderService;
    @Autowired
    private GeoreMachineService georeMachineService;
    @Autowired
    private MachineFeeBoundDao machineFeeBoundDao;
    @Autowired
    private BrandRemoteConfigService brandRemoteConfigService;
    @Autowired
    private AccountUserService accountUserService;
    @Autowired
    private DispatchLogService dispatchLogService;
    @Autowired
    private PowerChangeLogExpandService powerChangeLogExpandService;
    @Autowired
    private AccountConfigExtService accountConfigExtService;

    @Override
    //@Scheduled(cron = "0 9/10 * * * ?")
    /**无信号检测定时任务*/
    public void offlineTask() {
        // 10分钟
        LogUtil.info("无信号检测定时任务");
        long t1 = System.currentTimeMillis();

        /**加载无信号设备id*/
        List<Integer> abnormalMachineIds = machineAbnormalService.getByAbnormalType(MachineAbnormalConstant.MACHINE_ABNORMAL_WXH);
        if (abnormalMachineIds != null && abnormalMachineIds.size() > 0) {
            /**获取无信号设备编号*/
            List<String> machineNos = machineService.getMachineNOByIds(abnormalMachineIds, null);
            /**判断电量时间是否大于10分钟*/
            List<String> terMachineNO10s = terBatteryService.getNosAfterTimeEU(StringUtil.getStringListString(machineNos), DateTimeUtil.getNowTimeBefore(-10), null);
            terMachineNO10s = terMachineNO10s.stream().filter(e -> e != null).collect(Collectors.toList());
            /**无信号异常解除*/
            if (terMachineNO10s != null && terMachineNO10s.size() > 0) {
                List<Integer> machineIds = machineService.getMachineIdByNOs(terMachineNO10s, null);
                machineAbnormalService.deleteBatch(machineIds, MachineAbnormalConstant.MACHINE_ABNORMAL_WXH);
            }
        }

        /**加载所有最后电量离线大于30分钟数据 */
        List<String> terMachineNO30s = terBatteryService.getByBeforeTime(DateTimeUtil.getNowTimeBefore(-30));
        if (terMachineNO30s != null && terMachineNO30s.size() > 0) {
            /**获取到设备id*/
            List<Integer> machineId30s = dataService.getByMachineIds(terMachineNO30s);
            /**获取新增的无信号车辆*/
            List<Integer> newAbnormalMachineIds = ListUtil.getSameIntegerList(machineId30s, abnormalMachineIds);
            newAbnormalMachineIds = newAbnormalMachineIds.stream().filter(e -> e != null).collect(Collectors.toList());
            /**批量新增*/
            if (newAbnormalMachineIds != null && newAbnormalMachineIds.size() > 0) {
                machineAbnormalService.insertBatch(newAbnormalMachineIds, MachineAbnormalConstant.MACHINE_ABNORMAL_WXH, DateTimeUtil.getNowTime());
            }
        }

        long t2 = System.currentTimeMillis();
        LogUtil.info("无信号检测定时任务时间" + (t2 - t1) + "ms");
    }

    @Override
    //@Scheduled(cron = "0 5/10 * * * ?")
    /**运维占用超时锁车定时任务*/
    public void machineOccpyLockTask() {
        LogUtil.info("运维占用超时锁车定时任务");
        // 10分钟
        long t1 = System.currentTimeMillis();

        /**清除已经激活车辆*/
        machineOccupyService.delActive();

        /**用户骑行,取消运维占用*/
        machineOccupyService.delBorrow();

        /**查询所有运维占用数据*/
        List<MachineOccupy> machineOccupys = machineOccupyService.getAll();
        /**获取运维占用车辆id*/
        List<Integer> machineIds = machineOccupys.stream().map(MachineOccupy::getMachineId).collect(Collectors.toList());
        if (machineIds.size() > 0) {
            /**获取所有运维占用车辆信息*/
            List<Machine> machines = machineService.getByMachineIds(machineIds);
            Map<Integer, Machine> machineMap = new HashMap<>();
            for (Machine machine : machines) {
                machineMap.put(machine.getMachineId(), machine);
            }
            for (MachineOccupy mo : machineOccupys) {
                try {
                    Machine machine = machineMap.get(mo.getMachineId());
                    if (machine != null) {
                        /**运维占用时间*/
                        Integer occupyTime = DateTimeUtil.getMinutes(mo.getUseTime(), DateTimeUtil.getNowTime());

                        /**占用超过10分钟，并且是锁车状态结束占用*/
                        MachineStatus machinestatus = dataService.getMachineStatus(machine.getMachineId());
                        if (occupyTime > 10 && IntegerUtil.getLockState(machinestatus.getTerStatus())) {
                            machineOccupyService.del(machine.getMachineId());
                            LogUtil.info("[" + machine.getUserCode() + "]已锁车，结束运维占用");
                            continue;
                        }
                        MachineEvent machineEvent = machineAttrService.getMachineEvent(machine.getMachineNO(), "tLSS");
                        if (machineEvent != null && !IntegerUtil.getLockState(Integer.parseInt(machineEvent.getEventValue()))) {
                            AccountConfig accountConfig = dataService.getAccountConfig(machine.getAccountId());
                            if (accountConfig != null && accountConfig.getAutoLockTime() > 0) {
                                /**运动忽略*/
                                MachineEvent machineEventRun = machineAttrService.getByMachineNO(machine.getMachineNO(), "1");
                                if (machineEventRun != null) {
                                    continue;
                                }

                                /**占用时间小于自动上锁时间忽略*/
                                if (occupyTime <= accountConfig.getAutoLockTime()) {
                                    continue;
                                }

                                /**判断车辆是否静止*/
                                Boolean isLock = false;
                                MachineEvent machineEventStop = machineAttrService.getByMachineNO(machine.getMachineNO(), "0");
                                if (machineEventStop != null) {
                                    Integer stopTime = DateTimeUtil.getMinutes(machineEventStop.getEventTime(), DateTimeUtil.getNowTime());

                                    if (stopTime > accountConfig.getAutoLockTime()) {
                                        /**自行车不判断里程*/
                                        if (machine.getMachineType() == 1) {
                                            isLock = true;
                                        } else {

                                            String startTime = DateTimeUtil.getMinsAgo(accountConfig.getAutoLockTime());
                                            Integer mileage = historyService.getMileageByMachineNOAndTime(machine.getMachineNO(), startTime, DateTimeUtil.getNowTime());
                                            if (mileage == null) {
                                                mileage = 0;
                                            }
                                            if (mileage < 100) {
                                                isLock = true;
                                            }
                                        }

                                    }
                                } else {
                                    /**占用时间大于设定时间*/
                                    if (DateTimeUtil.getMinutes(mo.getUseTime(), DateTimeUtil.getNowTime()) < accountConfig.getAutoLockTime()) {
                                        continue;
                                    }
                                    if (machine.getMachineType() == 1) {
                                        isLock = true;
                                    } else {
                                        /**里程校验*/
                                        String startTime = DateTimeUtil.getMinsAgo(accountConfig.getAutoLockTime());
                                        Integer mileage = historyService.getMileageByMachineNOAndTime(machine.getMachineNO(), startTime, DateTimeUtil.getNowTime());
                                        if (mileage == null) {
                                            mileage = 0;
                                        }
                                        if (mileage < 100) {
                                            isLock = true;
                                        }
                                    }

                                }

                                if (isLock) {
                                    String serNO = UUID.randomUUID().toString();
                                    terControlService.sendControl(serNO, machine.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCK, "");
                                    /**车辆取消占用*/
                                    redisService.add(RedisConstant.REDIS_machineLockMap + serNO, machine.getMachineId().toString(), 86400);
                                    /**指令日志*/
                                    setOrderLog(machine, serNO, ControlTypeConstant.CONTROL_TYPE_LOCK, "运维占用静止超时锁车");
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    log.info("错误:{}", e);
                }
            }
        }
        long t2 = System.currentTimeMillis();
        LogUtil.info("运维占用超时锁车定时任务时间" + (t2 - t1) + "ms");
    }

    @Override
    //@Scheduled(cron = "0 2/10 * * * ?")
    /**新增电池异常定时任务*/
    public void batAmnormalTask() {
        LogUtil.info("新增电池异常定时任务");
        // 10分钟
        long t1 = System.currentTimeMillis();

        /**加载电池异常的设备*/
        List<Integer> machineIdAbnormals = machineAbnormalService.getByAbnormalType(MachineAbnormalConstant.MACHINE_ABNORMAL_DCYC);
        if (machineIdAbnormals != null && machineIdAbnormals.size() > 0) {
            /**获取电池异常设备编号*/
            List<String> machineNos = machineService.getMachineNOByIds(machineIdAbnormals, null);

            /**获取自行车异常编号*/
            List<String> machineNoZs = machineService.getMachineNOByIds(machineIdAbnormals, MachineStateConstant.ZZC);

            /**判断电量时间是否大于10分钟，电压大于30V*/
            List<String> terMachineNOs = terBatteryService.getNosAfterTimeEU(StringUtil.getStringListString(machineNos), DateTimeUtil.getNowTimeBefore(-10), 30000);
            terMachineNOs = terMachineNOs.stream().filter(e -> e != null).collect(Collectors.toList());
            /**电池异常异常解除*/
            if (terMachineNOs != null && terMachineNOs.size() > 0) {
                terMachineNOs.addAll(machineNoZs);
                List<Integer> machineIds = machineService.getMachineIdByNOs(terMachineNOs, null);
                machineAbnormalService.deleteBatch(machineIds, MachineAbnormalConstant.MACHINE_ABNORMAL_DCYC);
            }
        }

        /**加载电压小于10V的数据*/
        List<String> terMachineNO10Vs = terBatteryService.getBatteryEU(10000);
        if (terMachineNO10Vs != null && terMachineNO10Vs.size() > 0) {
            /**获取到设备id*/
            List<Integer> machineId10s = machineService.getMachineIdByNOs(terMachineNO10Vs, MachineStateConstant.DDC);
            /**获取新增的电池车辆*/
            List<Integer> newAbnormalMachineIds = ListUtil.getSameIntegerList(machineId10s, machineIdAbnormals);
            newAbnormalMachineIds = newAbnormalMachineIds.stream().filter(e -> e != null).collect(Collectors.toList());
            /**批量新增*/
            if (newAbnormalMachineIds != null && newAbnormalMachineIds.size() > 0) {
                machineAbnormalService.insertBatch(newAbnormalMachineIds, MachineAbnormalConstant.MACHINE_ABNORMAL_DCYC, DateTimeUtil.getNowTime());
            }
        }

        long t2 = System.currentTimeMillis();
        LogUtil.info("新增电池异常定时任务时间" + (t2 - t1) + "ms");
    }

    @Override
    //@Scheduled(cron = "0 3/5 * * * ?")
    /**超区、（站外、禁停区）异常定时任务*/
    public void areaAbnormalTask() {
        // 5分钟
        LogUtil.info("超区、（站外、禁停区）异常定时任务");
        long t1 = System.currentTimeMillis();

        /**获取最后定时时间20分钟内车辆*/
        List<Integer> machineStatuses = machineStatusService.getByPosDt(DateTimeUtil.getMinsAgo(150));

        /** 获取当前骑行中车辆 */
        Map<Integer, MachineBorrow> machineBorrowMap = new HashMap<Integer, MachineBorrow>();
        List<MachineBorrow> machineBorrows = machineBorrowService.getAll();
        for (MachineBorrow mb : machineBorrows) {
            machineBorrowMap.put(mb.getMachineId(), mb);
        }
        machineStatuses = machineStatuses.stream().filter(e -> e != null).collect(Collectors.toList());

        if (machineStatuses.size() > 0) {
            /**获取中设备编号*/
            List<String> machineNOBorrows = machineService.getMachineNOByIds(machineStatuses, null);
            /**设备最后位置*/
            List<TerLastPos> terLastPoses = terPositionService.getByMachineNOBatch(machineNOBorrows);

            /**获取所有车辆信息*/
            List<Machine> machines = machineService.getByMachineIds(machineStatuses);
            Map<String, Machine> machineMap = new HashMap<>();
            for (Machine machine : machines) {
                machineMap.put(machine.getMachineNO(), machine);
            }

            /**获取所有异常车辆*/
            List<Integer> abnormalType = new ArrayList<>();
            //超区
            abnormalType.add(MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY);
            //禁停区
            abnormalType.add(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC);
            //站外
            abnormalType.add(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW);

            //获取异常车辆
            List<MachineAbnormal> machineAbnormals = machineAbnormalService.getByType(abnormalType);
            Map<String, MachineAbnormal> machineAbnormalMap = new HashMap<>();
            for (MachineAbnormal machineAbnormal : machineAbnormals) {
                machineAbnormalMap.put(machineAbnormal.getMachineId() + ":" + machineAbnormal.getAbnormalType(), machineAbnormal);
            }
            //新增异常集合
            Map<Integer, List<Integer>> addMapType = new HashMap<>();
            //删除异常集合
            Map<Integer, List<Integer>> delMapType = new HashMap<>();

            //获取站外判定误差范围
            List<AccountConfigExt> AccountConfigExtList = accountConfigExtService.getAll();
            Map<Integer, Integer> offParkPointAllowRangeMap = AccountConfigExtList.stream()
                    .filter(e -> Objects.equals(e.getParamKey(), AccountConfigExtConstant.OFF_PARK_POINT_ALLOW_RANGE))
                    .collect(Collectors.toMap(AccountConfigExt::getAccountId, e -> Integer.parseInt(e.getParamValue())));
            Map<Integer, Integer> offParkPointEnableMap = AccountConfigExtList.stream()
                    .filter(e -> Objects.equals(e.getParamKey(), AccountConfigExtConstant.OFF_PARK_POINT_ENABLE))
                    .collect(Collectors.toMap(AccountConfigExt::getAccountId, e -> Integer.parseInt(e.getParamValue())));
            for (TerLastPos tlp : terLastPoses) {
                try {
                    /** 离线时间 */
                    Machine machine = machineMap.get(tlp.getMachineNO());
                    if (machine != null) {
                        /**获取围栏*/
                        List<Point> points = dataService.getGeo(machine.getAccountId());
                        /**在骑车辆*/
                        MachineBorrow machineBorrow = machineBorrowMap.get(machine.getMachineId());

                        if (CollUtil.isNotEmpty(points)) {
                            /** 判断是否在区域内 */
                            Boolean isInArea = GeoUtil.IsPtInPoly(new Point(tlp.getLon(), tlp.getLat()), points);
                            if (isInArea) {
                                MachineAbnormal maArea = machineAbnormalMap.get(machine.getMachineId() + ":" + MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY);
                                if (maArea != null) {
                                    if (delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY) != null) {
                                        delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY).add(machine.getMachineId());
                                    } else {
                                        List<Integer> delCCQY = new ArrayList();
                                        delCCQY.add(machine.getMachineId());
                                        delMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY, delCCQY);
                                    }
                                }

                                AccountConfig ac = dataService.getAccountConfig(machine.getAccountId());
                                if (ac != null && ac.getReturnModel() == 1) {
                                    /**防止前面设置的是站点模式，删除站外异常*/
                                    if (delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW) != null) {
                                        delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW).add(machine.getMachineId());
                                    } else {
                                        List<Integer> delZW = new ArrayList();
                                        delZW.add(machine.getMachineId());
                                        delMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW, delZW);
                                    }

                                    /**判断是否在禁停区*/
                                    ProhibitArea probibitArea = prohibitAreaService.checkInProhibitArea(machine.getAccountId(), new Point(tlp.getLon(), tlp.getLat()), 3000);
                                    if (probibitArea != null) {
                                        MachineAbnormal maDB = machineAbnormalMap.get(machine.getMachineId() + ":" + MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC);
                                        if (maDB == null && machineBorrow == null) {
                                            if (addMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC) != null) {
                                                addMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC).add(machine.getMachineId());
                                            } else {
                                                List<Integer> addJTYC = new ArrayList();
                                                addJTYC.add(machine.getMachineId());
                                                addMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC, addJTYC);
                                            }
                                        }
                                    } else {
                                        MachineAbnormal ma = machineAbnormalMap.get(machine.getMachineId() + ":" + MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC);
                                        if (ma != null) {
                                            if (delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC) != null) {
                                                delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC).add(machine.getMachineId());
                                            } else {
                                                List<Integer> delJTYC = new ArrayList();
                                                delJTYC.add(machine.getMachineId());
                                                delMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC, delJTYC);
                                            }
                                        }
                                    }
                                } else {
                                    /**防止前面设置的是站点模式，删除禁停区异常*/
                                    if (delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC) != null) {
                                        delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC).add(machine.getMachineId());
                                    } else {
                                        List<Integer> delJTYC = new ArrayList();
                                        delJTYC.add(machine.getMachineId());
                                        delMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC, delJTYC);
                                    }

                                    /** 判断是否在站点 */
                                    Integer allowRange = null;
                                    Integer offParkPointEnable = offParkPointEnableMap.get(machine.getAccountId());
                                    Integer offParkPointAllowRange = offParkPointAllowRangeMap.get(machine.getAccountId());
                                    if (offParkPointEnable == 0) {
                                        allowRange = offParkPointAllowRange;
                                    }
                                    ParkPoint parkPoint = parkPointService.checkInParkPoint(machine.getAccountId(),
                                            new Point(tlp.getLon(), tlp.getLat()), 500, allowRange);
                                    if (parkPoint != null) {
                                        MachineAbnormal ma = machineAbnormalMap.get(machine.getMachineId() + ":" + MachineAbnormalConstant.MACHINE_ABNORMAL_ZW);
                                        if (ma != null) {
                                            if (delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW) != null) {
                                                delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW).add(machine.getMachineId());
                                            } else {
                                                List<Integer> delZW = new ArrayList();
                                                delZW.add(machine.getMachineId());
                                                delMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW, delZW);
                                            }
                                        }
                                    } else {
                                        MachineAbnormal maDB = machineAbnormalMap.get(machine.getMachineId() + ":" + MachineAbnormalConstant.MACHINE_ABNORMAL_ZW);
                                        if (maDB == null && machineBorrow == null) {
                                            if (addMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW) != null) {
                                                addMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW).add(machine.getMachineId());
                                            } else {
                                                List<Integer> addZW = new ArrayList();
                                                addZW.add(machine.getMachineId());
                                                addMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW, addZW);
                                            }
                                        }
                                    }
                                }
                            } else {

                                AccountConfig ac = dataService.getAccountConfig(machine.getAccountId());
                                if (ac != null && ac.getReturnModel() == 1) {
                                    /** 删除禁停区异常 */
                                    if (delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC) != null) {
                                        delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC).add(machine.getMachineId());
                                    } else {
                                        List<Integer> delJTYC = new ArrayList();
                                        delJTYC.add(machine.getMachineId());
                                        delMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_JTYC, delJTYC);
                                    }
                                } else {
                                    /** 删除站外异常 */
                                    if (delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW) != null) {
                                        delMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW).add(machine.getMachineId());
                                    } else {
                                        List<Integer> delZW = new ArrayList();
                                        delZW.add(machine.getMachineId());
                                        delMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_ZW, delZW);
                                    }
                                }

                                MachineAbnormal maDB = machineAbnormalMap.get(machine.getMachineId() + ":" + MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY);
                                if (maDB == null && machineBorrow == null) {
                                    if (addMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY) != null) {
                                        addMapType.get(MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY).add(machine.getMachineId());
                                    } else {
                                        List<Integer> addCCQY = new ArrayList();
                                        addCCQY.add(machine.getMachineId());
                                        addMapType.put(MachineAbnormalConstant.MACHINE_ABNORMAL_CCQY, addCCQY);
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    log.info("错误:{}", e);
                }
            }
            if (delMapType.size() > 0) {
                for (Integer key : delMapType.keySet()) {
                    machineAbnormalService.deleteBatch(delMapType.get(key), key);
                }
            }
            if (addMapType.size() > 0) {
                for (Integer key : addMapType.keySet()) {
                    machineAbnormalService.insertBatch(addMapType.get(key), key, DateTimeUtil.getNowTime());
                }
            }
        }
        long t2 = System.currentTimeMillis();
        LogUtil.info("超区、（站外、禁停区）异常定时任务时间" + (t2 - t1) + "ms");
    }

    @Override
    //@Scheduled(cron = "13/60 * * * * ?")
    /**静止超时临停结束订单定时任务*/
    public void autoStopFinish() {
        // 60秒
        LogUtil.info("静止超时临停结束订单定时任务");
        long t1 = System.currentTimeMillis();

        /**获取所有在骑车辆*/
        List<MachineBorrow> machineBorrows = machineBorrowService.getAll();
        List<String> orderNOs = machineBorrows.stream().map(MachineBorrow::getOrderNO).collect(Collectors.toList());
        /**查询骑行订单信息*/
        if (orderNOs != null && orderNOs.size() > 0) {
            List<RideLog> rideLogList = rideLogService.getByOrderNOs(orderNOs);
            Map<String, RideLog> rideLogMap = new HashMap<>();
            for (RideLog rideLog : rideLogList) {
                rideLogMap.put(rideLog.getMachineNO(), rideLog);
            }


            /** 获取配置自动停车和结束订单代理商 */
            for (AccountConfig ac : dataService.getAllAccountConfig()) {


                if (ac.getFinishOrderSwitch()) {
                    /** 查询当前骑行车辆 */
                    List<Machine> machines = machineService.getUseingByAccountId(ac.getAccountId());
                    List<String> machineNOs = machines.stream().map(Machine::getMachineNO).collect(Collectors.toList());

                    if (machineNOs.size() > 0) {
                        /**查询车辆事件*/
                        Map<String, MachineEvent> machineStopMap = new HashMap<String, MachineEvent>();
                        List<MachineEvent> machineStops = machineAttrService.getStopByMachineNOBatch(machineNOs);
                        for (MachineEvent ms : machineStops) {
                            machineStopMap.put(ms.getMachineNO(), ms);
                        }


                        for (Machine machine : machines) {
                            try {
                                /**未激活车辆忽略，单车也忽略*/
                                MachineStatus ms = dataService.getMachineStatus(machine.getMachineId());
                                if (ms == null) {
                                    continue;
                                }
                                RideLog rideLog = rideLogMap.get(machine.getMachineNO());
                                User user = userService.getByUserId(rideLog.getUserId());
                                Integer rideTime = DateTimeUtil.getMinutes(rideLog.getStartTime(), DateTimeUtil.getNowTime());
                                Boolean finishOrder = false;
                                Integer stopTime = null;
                                /**获取静止时间*/
                                MachineEvent machineStop = machineStopMap.get(machine.getMachineNO());


                                if (machineStop != null) {
                                    /**有临停记录*/
                                    Park parkStart = parkService.getByMachineId(machine.getMachineId());

                                    if (parkStart != null) {

                                        Integer endTime = null;

                                        if (parkStart.getRemark().contains("静止超时，系统自动中途停车")) {
                                            endTime = ac.getFinishTime() - ac.getStopTime();
                                        } else {
                                            endTime = ac.getFinishTime();
                                        }

                                        Integer finishIng = DateTimeUtil.getMinutes(parkStart.getStartTime(), DateTimeUtil.getNowTime());


                                        if (endTime >= 10) {
                                            /**客户端订单推送小程序*/
                                            if (endTime - finishIng == 10) {
                                                String order = redisService.get(RedisConstant.REDIS_TER_BIKE_RIDELOG_PUSH + machine.getMachineNO());
                                                if (order == null) {
                                                    redisService.add(RedisConstant.REDIS_TER_BIKE_RIDELOG_PUSH + machine.getMachineNO(), rideLog.getOrderNO(), 800);
                                                    UQHttpClient.sendLockMsg(rideLog, user.getAccountId());
                                                }
                                            }
                                        }

                                        if (ac.getFinishTime() > 0 && ac.getStopTime() > 0 && finishIng >= endTime) {
                                            /**骑行时间小于设定的静止结束时间*/
                                            if (rideTime <= ac.getFinishTime()) {
                                                continue;
                                            }
                                            finishOrder = true;
                                        }

                                    } else {

                                        stopTime = DateTimeUtil.getMinutes(machineStop.getEventTime(), DateTimeUtil.getNowTime());

                                        if (ac.getFinishTime() > 0 && stopTime > ac.getFinishTime()) {
                                            /**客户端订单推送小程序*/
                                            if (ac.getFinishTime() - stopTime == 10) {
                                                String order = redisService.get(RedisConstant.REDIS_TER_BIKE_RIDELOG_PUSH + machine.getMachineNO());
                                                if (order == null) {
                                                    redisService.add(RedisConstant.REDIS_TER_BIKE_RIDELOG_PUSH + machine.getMachineNO(), rideLog.getOrderNO(), 800);
                                                    UQHttpClient.sendLockMsg(rideLog, user.getAccountId());
                                                }
                                            }

                                            /**骑行时间小于设定的静止结束时间*/
                                            if (rideTime <= ac.getFinishTime()) {
                                                continue;
                                            }

                                            if (machine.getMachineType() == 1) {
                                                finishOrder = true;
                                            } else {
                                                /**双重校验，设定时间里程也需要小于100米*/
                                                String startTime = DateTimeUtil.getMinsAgo(ac.getFinishTime());
                                                Integer mileage = historyService.getMileageByMachineNOAndTime(machine.getMachineNO(), startTime, DateTimeUtil.getNowTime());
                                                if (mileage == null) {
                                                    mileage = 0;
                                                }
                                                if (mileage < 100) {
                                                    finishOrder = true;
                                                }
                                            }
                                        }
                                        /** 是否临时停车*/
                                        if (ac.getStopTime() > 0 && stopTime > ac.getStopTime() && !finishOrder) {


                                            /**骑行时间小于设定的静止临停时间*/
                                            if (rideTime <= ac.getStopTime()) {
                                                continue;
                                            }

                                            /**判断是否车辆运动中*/
                                            MachineEvent machineEvent = machineAttrService.getByMachineNO(machine.getMachineNO(), "1");

                                            if (machineEvent != null) {
                                                Integer runTime = DateTimeUtil.getMinutes(machineEvent.getEventTime(), DateTimeUtil.getNowTime());
                                                if (runTime <= ac.getStopTime()) {
                                                    continue;
                                                }
                                            }

                                            Park parkDB = parkService.getByMachineId(machine.getMachineId());
                                            if (parkDB == null) {
                                                if (machine.getMachineType() == 1) {
                                                } else {
                                                    /**双重校验，设定时间里程也需要小于100米*/
                                                    String startTime = DateTimeUtil.getMinsAgo(ac.getStopTime());
                                                    Integer mileage = historyService.getMileageByMachineNOAndTime(machine.getMachineNO(), startTime, DateTimeUtil.getNowTime());
                                                    if (mileage == null) {
                                                        mileage = 0;
                                                    }
                                                    if (mileage > 100) {
                                                        continue;
                                                    } else {
                                                    }
                                                }

                                                /** 上锁 */
                                                String serNO = UUID.randomUUID().toString();

                                                /** 蓝牙是否支持新的语音 */
                                                boolean blueTooth = UQHttpClient.getMachineBluetooth(machine.getUserCode());
                                                LogUtil.info(machine.getUserCode() + "播报新语音判断" + blueTooth);
                                                String controlType = null;
                                                if (!blueTooth) {
                                                    controlType = ControlTypeConstant.CONTROL_TYPE_LOCK;
                                                } else {
                                                    controlType = ControlTypeConstant.CONTROL_TYPE_PARKRIDE;
                                                }

                                                /**添加临停缓存*/
                                                redisService.add(RedisConstant.MACHINE_PARK + serNO, rideLog.getOrderNO(), 30);

                                                terControlService.sendControl(serNO, machine.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, controlType, "");

                                                /** 临时停车 */
                                                String finalControlType = controlType;

                                                /**指令日志*/
                                                setOrderLog(machine, serNO, finalControlType, "系统超时自动临停");
                                            }
                                        }
                                    }
                                } else {
                                    /**判断是否车辆运动中*/
                                    MachineEvent machineEvent = machineAttrService.getByMachineNO(machine.getMachineNO(), "1");
                                    if (machineEvent != null) {
                                        Integer runTime = DateTimeUtil.getMinutes(machineEvent.getEventTime(), DateTimeUtil.getNowTime());

                                        if (runTime <= ac.getFinishTime()) {
                                            continue;
                                        }
                                    }

                                    /**客户端订单推送小程序*/
                                    if (ac.getFinishTime() - rideTime == 10) {
                                        String order = redisService.get(RedisConstant.REDIS_TER_BIKE_RIDELOG_PUSH + machine.getMachineNO());
                                        if (order == null) {
                                            redisService.add(RedisConstant.REDIS_TER_BIKE_RIDELOG_PUSH + machine.getMachineNO(), rideLog.getOrderNO(), 800);
                                            UQHttpClient.sendLockMsg(rideLog, user.getAccountId());
                                        }
                                    }

                                    /**防止终端静止时间不准确导致不能结束订单*/
                                    if (ac.getFinishTime() > 0 && rideTime > ac.getFinishTime()) {
                                        if (machine.getMachineType() == 1) {
                                            finishOrder = true;
                                        } else {
                                            String startTime = DateTimeUtil.getMinsAgo(ac.getFinishTime());
                                            Integer mileage = historyService.getMileageByMachineNOAndTime(machine.getMachineNO(), startTime, DateTimeUtil.getNowTime());
                                            if (mileage == null) {
                                                mileage = 0;
                                            }
                                            if (mileage < 100) {
                                                finishOrder = true;
                                            }
                                        }

                                    }
                                }

                                /**强制结束订单*/
                                if (finishOrder) {
                                    //User user = userService.getByUserId(rideLog.getUserId());

                                    /**借车状态关锁*/
                                    if (dataService.getMachineType(machine.getMachineId())) {
                                        String terStatus = redisService.get1(RedisConstant.MACHINE_NO_HELMET + user.getUserId());
                                        /**关锁*/
                                        if (terStatus != null && ObjectUtil.statusParse(11, Integer.valueOf(terStatus))) {
                                            LogUtil.info(user.getUserId() + "，用户借车，头盔锁状态关锁，车辆：" + machine.getUserCode());

                                            /**获取当前头盔锁状态*/
                                            String json = redisService.getGetWay(RedisUtil.getTerHashId(machine.getMachineNO()), RedisConstant.REDIS_TER_LAST_STATUS);
                                            if (json != null && json.length() > 0) {
                                                TerLastStatus terLastStatus = JSON.parseObject(json, TerLastStatus.class);
                                                Integer terStatusRedis = terLastStatus.getCarStatus();

                                                /**开锁*/
                                                if (!ObjectUtil.statusParse(11, Integer.valueOf(terStatusRedis))) {
                                                    LogUtil.info("超时结束订单开关锁状态：开锁" + machine.getUserCode());
                                                    String time = redisService.get(RedisConstant.MACHINE_NO_HELMET_MAIN + user.getUserId());
                                                    if (time != null) {
                                                        /**大于三个小时*/
                                                        if ((System.currentTimeMillis() - Long.valueOf(time)) > 10800000) {
                                                            redisService.del(RedisConstant.MACHINE_NO_HELMET_MAIN + user.getUserId());
                                                            LogUtil.info("大于三个小时锁车：" + machine.getUserCode());
                                                        } else {
                                                            LogUtil.info("小于三小时，不锁车：" + machine.getUserCode());
                                                            continue;
                                                        }
                                                    } else {
                                                        /**四个小时*/
                                                        redisService.add(RedisConstant.MACHINE_NO_HELMET_MAIN + user.getUserId(), System.currentTimeMillis() + "", 14400);
                                                        LogUtil.info("第一次检测关锁：" + machine.getUserCode());
                                                        continue;
                                                    }
                                                }
                                            }
                                        }

                                    }

                                    /** 强制结束订单 */
                                    /**查询骑行费用*/
                                    Integer money = UQHttpClient.getOrderMoney(rideLogMap.get(machine.getMachineNO()).getUserId());

                                    /**判断车辆是否超区*/
                                    Integer dispatchMoney = null;
                                    AccountFee accountFee = accountFeeService.getByAccountId(machine.getAccountId());

                                    if (accountFee != null && ms != null) {

                                        /**超区*/
                                        List<Point> points = dataService.getGeo(machine.getAccountId());

                                        /**自行车调度兼容自定义计费规则*/
                                        MachineFee machineFee = machineFeeBoundDao.getByMachineId(machine.getMachineId());
                                        if (machine.getMachineType() == 1 && machineFee != null && machineFee.getDispatchSwitch() == 1 && machineFee.getAreaMoney() > 0) {
                                            Boolean isInArea = GeoUtil.IsPtInPoly(new Point(ms.getLon(), ms.getLat()), points);
                                            if (!isInArea) {
                                                dispatchMoney = machineFee.getAreaMoney();
                                            }
                                        } else if (accountFee != null && points.size() > 0 && accountFee.getDispatchSwitch() == 1 && accountFee.getAreaMoney() > 0) {
                                            Boolean isInArea = GeoUtil.IsPtInPoly(new Point(ms.getLon(), ms.getLat()), points);
                                            if (!isInArea) {
                                                dispatchMoney = accountFee.getAreaMoney();
                                            }
                                        }

                                        /**判断是否站外、禁停区*/
                                        if (dispatchMoney == null) {
                                            /**打开站外、禁停区调度费开关*/
                                            if (ac.getAutoFinishParkPointFee() != null && ac.getAutoFinishParkPointFee() == 1) {
                                                /**判断是否是禁停区*/
                                                if (ac != null) {
                                                    if (ac.getReturnModel() == 0) {
                                                        /**判断是站外*/
                                                        ParkPoint parkPoint = parkPointService.checkInParkPoint(machine.getAccountId(), new Point(ms.getLon(), ms.getLat()), 300, null);
                                                        if (parkPoint == null) {
                                                            if (machine.getMachineType() == 1 && machineFee != null && machineFee.getDispatchSwitch() == 1 && machineFee.getAreaMoney() > 0) {
                                                                dispatchMoney = machineFee.getParkPointMoney();
                                                            } else {
                                                                dispatchMoney = accountFee.getParkPointMoney();
                                                            }
                                                        }
                                                        LogUtil.info(ms.getMachineNO() + "站外：" + dispatchMoney);
                                                    } else {
                                                        /**判断是否禁停区内*/
                                                        ProhibitArea prohibitArea = prohibitAreaService.checkInProhibitArea(machine.getAccountId(), new Point(ms.getLon(), ms.getLat()), 3000);
                                                        if (prohibitArea != null) {
                                                            if (machine.getMachineType() == 1 && machineFee != null && machineFee.getDispatchSwitch() == 1 && machineFee.getAreaMoney() > 0) {
                                                                dispatchMoney = machineFee.getParkPointMoney();
                                                            } else {
                                                                dispatchMoney = accountFee.getParkPointMoney();
                                                            }
                                                        }
                                                        LogUtil.info(ms.getMachineNO() + "禁停区：" + dispatchMoney);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    if (money != null) {
                                        DecimalFormat df = new DecimalFormat("#.##");
                                        StringBuffer remark = new StringBuffer();
                                        remark.append("骑行费用=" + df.format(money / 100D));
                                        remark.append("；系统超时自动结束订单");
                                        if (dispatchMoney != null) {
                                            /**添加调度日志*/
                                            money = money + dispatchMoney;
                                            remark.append(",调度还车，调度费用=" + df.format(dispatchMoney / 100D));
                                        }


                                        LogUtil.info("用户余额：" + user.getMoney() + "，扣款金额：" + money);
                                        if (user.getMoney() < money) {
                                            AccountConfig accountConfig = dataService.getAccountConfig(rideLog.getAccountId());
                                            if (accountConfig.getNotPayNotice() == 1) {

                                                /**判断是否兼容创蓝*/
                                                BrandRemoteConfig brandRemoteConfig = brandRemoteConfigService.getByAccountIdAndType(user.getAccountId(), BrandRemoteConfigConstant.CL_SMS);
                                                if (brandRemoteConfig != null) {
                                                    String[] paramKV = brandRemoteConfig.getParamKV().split("&");
                                                    String accountSms = paramKV[0].substring(paramKV[0].lastIndexOf("=") + 1);
                                                    String passwordSms = paramKV[1].substring(paramKV[1].lastIndexOf("=") + 1);
                                                    /* 发送短信*/
                                                    ThreadPoolHelper.submit(new Runnable() {
                                                        @Override
                                                        public void run() {
                                                            try {
                                                                if (user.getPhone() != null) {
                                                                    ClzySmsAuthUtil.sendSms(accountSms, passwordSms, "您有一笔" + rideLog.getStartTime() + "的订单未支付，为了避免影响你的信用和下次骑行，请及时支付。", user.getPhone());
                                                                    redisService.add(rideLog.getOrderNO(), user.getPhone(), 60 * 60);
                                                                }
                                                            } catch (Exception e) {
                                                                LogUtil.info(user.getPhone() + "发送未支付短信失败");
                                                                log.error(e.getMessage(), e);
                                                            }
                                                        }
                                                    });
                                                } else {
                                                    AccountSmsModel accountSmsModel = dataService.getAccountSmsModel(user.getAccountId() + ":" + AccountSmsModelConstant.SMS_WZFLJ);
                                                    String linkUrl = UQHttpClient.WZFlink(user.getAccountId());
                                                    String notPaySms = redisService.get(rideLog.getOrderNO());
                                                    if (notPaySms == null) {
                                                        if (accountSmsModel != null) {
                                                            /* 发送短信*/
                                                            ThreadPoolHelper.submit(new Runnable() {
                                                                @Override
                                                                public void run() {
                                                                    try {
                                                                        XCSmsClient.notPaymentLink(user.getPhone(), rideLog.getStartTime(), smsAuthConfigService.getByAccountId(user.getAccountId()).getSmsCodeKey(), accountSmsModel.getModelId(), linkUrl);
                                                                        redisService.add(rideLog.getOrderNO(), user.getPhone(), 60 * 60);
                                                                    } catch (Exception e) {
                                                                        LogUtil.info(user.getPhone() + "发送未支付短信失败");
                                                                    }
                                                                }
                                                            });
                                                        }
                                                    }
                                                }


                                            }
                                        }
                                        UQHttpManager.finish(machine.getUserCode(), String.valueOf(money), remark.toString());
                                    }

                                    /** 上锁 */
                                    String serNO = UUID.randomUUID().toString();
                                    terControlService.sendControl(serNO, machine.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCK, "");

                                    /**指令日志*/
                                    setOrderLog(machine, serNO, ControlTypeConstant.CONTROL_TYPE_LOCK, "自动强制结束订单");
                                }
                            } catch (Exception e) {
                                log.error(e.getMessage(), e);
                                log.info("错误:{}", e);
                            }
                        }
                    }
                }
            }
        }

        long t2 = System.currentTimeMillis();
        LogUtil.info("静止超时临停结束订单定时任务时间" + (t2 - t1) + "ms");
    }

    @Override
    //@Scheduled(cron = "10/15 * * * * ?")
    /**判断换电定时任务*/
    public void changeBatteryTask() {
        LogUtil.info("判断换电定时任务");
        long t1 = System.currentTimeMillis();
        // 15秒
        /** 查询当前在换电的记录 */
        Map<String, String> machineBatteryMap = redisService.getAll(RedisConstant.REDIS_TER_BIKE_BATTERY_CHANGE_MAP);
        if (machineBatteryMap.size() > 0) {
            for (String machineNO : machineBatteryMap.keySet()) {
                try {
                    Long changeTime = Long.valueOf(machineBatteryMap.get(machineNO));

                    LogUtil.info("判断换电：" + machineNO);
                    /** 查询换电记录 */
                    String powerChangeLogString = redisService.get(RedisConstant.REDIS_TER_BATTERY_CHANGE + machineNO);
                    if (powerChangeLogString != null) {
                        PowerChangeLog pclNew = new PowerChangeLog();
                        try {
                            pclNew = JSONObject.parseObject(powerChangeLogString, PowerChangeLog.class);
                        } catch (JSONException e) {
                            redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE + machineNO);
                        }


                        if (pclNew.getPowerChangeCheck() != null && pclNew.getPowerChangeCheck().equals(0)) {
                            continue;
                        }

                        /** 获取最后状态 */
                        MachineStatus machineStatusNew = machineStatusService.getByMachineId(pclNew.getMachineId());

                        pclNew.setNewSoc(machineStatusNew.getSocPercent());
                        pclNew.setRemark(pclNew.getRemark() + "换电后电压=" + machineStatusNew.getBatteryEU() + ";");

                        /**
                         * 判断分区
                         */
                        GeoreMachine georeMachine = georeMachineService.getByMachineId(pclNew.getMachineId());
                        if (georeMachine != null) {
                            pclNew.setRegionId(georeMachine.getRegionId());
                        }

                        /** 换电超过30s后才能触发 */
                        if ((System.currentTimeMillis() - changeTime) > 30000 && (System.currentTimeMillis() - changeTime) < 600000) {

                            LogUtil.info("判断换电：" + machineNO);

                            /** 电量百分比等于-1忽略,换电后的电量需要大于换电前的电量 */
                            if (pclNew.getNewSoc() != -1 && (pclNew.getNewSoc() > pclNew.getOldSoc())) {

                                LogUtil.info("大于换电前的电量：" + pclNew.getMachineNO());

                                /** 添加数据库 */
                                if (dataService.getAccountConfig(pclNew.getAccountId()).getSocLimitIsValid() == null ||
                                        pclNew.getNewSoc() >= dataService.getAccountConfig(pclNew.getAccountId()).getSocLimitIsValid()) {

                                    /** 获取redis中数据，推送MQ*/
                                    String powerChangeMQString = redisService.get(RedisConstant.REDIS_TER_BATTERY_CHANGE + "MQ" + machineNO);
                                    if (powerChangeMQString != null) {
                                        List<TerControlMsg<PowerChangeMQ>> list = new LinkedList<>();
                                        PowerChangeMQ powerChangeMQ = new PowerChangeMQ();
                                        try {
                                            powerChangeMQ = JSON.parseObject(powerChangeMQString, PowerChangeMQ.class);
                                        } catch (JSONException e) {
                                            redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE + "MQ" + machineNO);
                                        }

                                        powerChangeMQ.setNewVol((double) machineStatusNew.getBatteryEU());
                                        TerControlMsg<PowerChangeMQ> terControlMsg = new TerControlMsg<PowerChangeMQ>();
                                        terControlMsg.setFeedback("tbit_uqbike_web_ai");
                                        terControlMsg.setMsgId(GatewayProtocol.MQ_MSG_ID_AROUND_MSG_PUSH);
                                        terControlMsg.setData(powerChangeMQ);
                                        list.add(terControlMsg);
                                        /**发送到MQ*/
                                        mqProducer.sendDataToQueue("tbit_uqbike_web_ai", JSON.toJSONString(list));
                                    }

                                    //有效换电，排除
                                    pclNew.setIsValid(1);
                                    LogUtil.info("[" + machineNO + "]有效换电");
                                    pclNew.setRemark("换电后电量：" + pclNew.getNewSoc() + "，大于换电有效值电量：" + dataService.getAccountConfig(pclNew.getAccountId()).getSocLimitIsValid());

                                    if (pclNew.getPowerChangeCheck() != null && pclNew.getPowerChangeCheck().equals(1)) {
                                        powerChangeLogService.updatePcl(pclNew);
                                    } else {
                                        powerChangeLogService.insert(pclNew);
                                    }

                                    /**是否存在领取工单信息*/
                                    LogUtil.info("换电工单有效判断：" + machineStatusNew.getMachineId());
                                    Machine machine = dataService.getMachine(machineStatusNew.getMachineId());
                                    AccountUser accountUser = accountUserService.getById(pclNew.getUserMainId());
                                    workOrderService.endWork(WorkOrderConstant.workType_HD, accountUser, machine.getMachineId(), pclNew.getPowerChangeLogId(), pclNew.getIsValid(), null, WorkOrderConstant.state_WC);

                                    /** 删除map中数据 */
                                    redisService.del(RedisConstant.REDIS_TER_BIKE_BATTERY_CHANGE_MAP, machineNO);

                                    /** 删除redis中数据 */
                                    redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE + machineNO);

                                    /** 删除redis中数据，推送MQ*/
                                    redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE + "MQ" + machineNO);
                                }
                            }
                        }

                        /** 超过10分钟清除 */
                        if ((System.currentTimeMillis() - changeTime) > 600000) {

                            /** 获取redis中数据，推送MQ*/
                            String powerChangeMQString = redisService.get(RedisConstant.REDIS_TER_BATTERY_CHANGE + "MQ" + machineNO);
                            if (powerChangeMQString != null) {
                                List<TerControlMsg<PowerChangeMQ>> list = new LinkedList<>();
                                PowerChangeMQ powerChangeMQ = new PowerChangeMQ();
                                try {
                                    powerChangeMQ = JSON.parseObject(powerChangeMQString, PowerChangeMQ.class);
                                } catch (JSONException e) {
                                    redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE + "MQ" + machineNO);
                                }

                                powerChangeMQ.setNewVol((double) machineStatusNew.getBatteryEU());
                                TerControlMsg<PowerChangeMQ> terControlMsg = new TerControlMsg<PowerChangeMQ>();
                                terControlMsg.setFeedback("tbit_uqbike_web_ai");
                                terControlMsg.setMsgId(GatewayProtocol.MQ_MSG_ID_AROUND_MSG_PUSH);
                                terControlMsg.setData(powerChangeMQ);
                                list.add(terControlMsg);
                                /**发送到MQ*/
                                mqProducer.sendDataToQueue("tbit_uqbike_web_ai", JSON.toJSONString(list));
                            }

                            if (pclNew.getNewSoc() == null) {
                                pclNew.setIsValid(0);
                                LogUtil.info("[" + machineNO + "][" + machineStatusNew.getBatDt() + "][" + pclNew.getOldSoc() + "]->[" + machineStatusNew.getSocPercent() + "]无效换电，清除10分钟换电");

                            } else {
                                /** 添加数据库 */
                                if (dataService.getAccountConfig(pclNew.getAccountId()).getSocLimitIsValid() == null ||
                                        pclNew.getNewSoc() >= dataService.getAccountConfig(pclNew.getAccountId()).getSocLimitIsValid()) {
                                    //有效换电，排除
                                    pclNew.setIsValid(1);
                                    LogUtil.info("[" + machineNO + "]有效换电");
                                    pclNew.setRemark("换电后电量：" + pclNew.getNewSoc() + "，大于换电有效值电量：" + dataService.getAccountConfig(pclNew.getAccountId()).getSocLimitIsValid());
                                } else {
                                    pclNew.setIsValid(0);
                                    pclNew.setRemark("换电后电量：" + pclNew.getNewSoc() + "，小于换电有效值电量：" + dataService.getAccountConfig(pclNew.getAccountId()).getSocLimitIsValid());
                                }
                            }

                            if (pclNew.getPowerChangeCheck() != null && pclNew.getPowerChangeCheck().equals(1)) {
                                powerChangeLogService.updatePcl(pclNew);
                            } else {
                                powerChangeLogService.insert(pclNew);
                            }

                            /**是否存在领取工单信息*/
                            LogUtil.info("换电工单有效判断：" + machineStatusNew.getMachineId());
                            Machine machine = dataService.getMachine(machineStatusNew.getMachineId());
                            AccountUser accountUser = accountUserService.getById(pclNew.getUserMainId());
                            workOrderService.endWork(WorkOrderConstant.workType_HD, accountUser, machine.getMachineId(), pclNew.getPowerChangeLogId(), pclNew.getIsValid(), null, WorkOrderConstant.state_WC);

                            /** 删除map中数据 */
                            redisService.del(RedisConstant.REDIS_TER_BIKE_BATTERY_CHANGE_MAP, machineNO);

                            /** 删除redis中数据 */
                            redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE + machineNO);

                            /** 删除redis中数据，推送MQ*/
                            redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE + "MQ" + machineNO);
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    log.info("错误:{}", e);
                }
            }
        }
        long t2 = System.currentTimeMillis();
        LogUtil.info("判断换电定时任务时间" + (t2 - t1) + "ms");
    }

    @Override
    //@Scheduled(cron = "1/30 * * * * ?")
    /**无占用无订单自动锁车任务*/
    public void unOccupyLock() {
        // 30秒
        LogUtil.info("无占用无订单自动锁车任务");
        long t1 = System.currentTimeMillis();
        /**查询未锁车车辆*/
        List<String> machineNOs = machineAttrService.getUnLockMachine();
        if (machineNOs.size() > 0) {
            /**查询数据*/
            List<Machine> machines = machineService.getUnLock(machineNOs);
            if (machines.size() > 0) {
                for (Machine machine : machines) {
                    try {
                        /**二次确认是否用户骑行或者运维占用，防止时间差或者并发导致的误判*/
                        Integer machineId = machineService.getOccupy(machine.getMachineId());
                        if (machineId == null) {
                            LogUtil.info("占用锁车二次判断忽略[" + machine.getMachineNO() + "]");
                            continue;
                        }
                        /**下发锁车指令*/
                        String serNO = UUID.randomUUID().toString();
                        terControlService.sendControl(serNO, machine.getMachineNO(), ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_LOCK, "");

                        /**指令日志*/
                        setOrderLog(machine, serNO, ControlTypeConstant.CONTROL_TYPE_LOCK, "无占用锁车");

                    } catch (Exception e) {
                        log.info("错误:{}", e);
                    }
                }
            }
        }
        long t2 = System.currentTimeMillis();
        LogUtil.info("无占用无订单自动锁车定时任务时间" + (t2 - t1) + "ms");
    }

    //@Scheduled(cron = "0 1/10 * * * ?")

    /**
     * 判断换电工单，调度记录定时任务
     */
    public void changeBatterWorkOrder() {
        LogUtil.info("判断换电工单，调度记录定时任务");
        long t1 = System.currentTimeMillis();

        /** 查询当前调度记录的记录 */
        Map<String, String> machineDispatchMap = redisService.getAll(RedisConstant.REDIS_TER_BIKE_DISPATCH_CHANGE_RIDE_MAP);

        if (machineDispatchMap.size() > 0) {
            String newTime = DateTimeUtil.getNowTime();
            for (String machineNO : machineDispatchMap.keySet()) {

                DispatchConfig dispatchConfig = dataService.getDispatch(dataService.getAccountId(machineNO));
                LogUtil.info("调度定时任务：" + machineNO + "dispatchConfig" + dispatchConfig.toString());
                String redis = redisService.get(RedisConstant.REDIS_TER_DISPATCH_CHANGE_RIDE + machineNO);
                LogUtil.info("调度定时任务获取调度缓存：" + redis);
                if (redis != null) {
                    List<PowerChangeRedis> powerChangeRedisList = new LinkedList<>();
                    try {
                        powerChangeRedisList = JSON.parseArray(redis, PowerChangeRedis.class);
                    } catch (JSONException e) {
                        redisService.del(RedisConstant.REDIS_TER_DISPATCH_CHANGE_RIDE + machineNO);
                    }

                    if (powerChangeRedisList != null && powerChangeRedisList.size() > 0) {
                        /**循环遍历多个审核中记录*/
                        Iterator<PowerChangeRedis> it = powerChangeRedisList.iterator();
                        while (it.hasNext()) {
                            PowerChangeRedis powerChangeRedis = it.next();

                            if ((DateTimeUtil.getTime(powerChangeRedis.getTime(), newTime)) > powerChangeRedis.getRideTime() * 3600) {

                                DispatchLog dispatchLog = dispatchLogService.getById(powerChangeRedis.getPowerChangeId());
                                dispatchLogService.audit(powerChangeRedis.getPowerChangeId(), WorkOrderConstant.isValid, dispatchLog.getRemark() + WorkOrderConstant.sys_rideTime_Valid, newTime);

                                /**审核后删除*/
                                it.remove();
                            }
                        }
                    }

                    /**判断是否为空，删除缓存*/
                    if (powerChangeRedisList != null && powerChangeRedisList.size() > 0) {
                        redisService.add(RedisConstant.REDIS_TER_DISPATCH_CHANGE_RIDE + machineNO, JSONObject.toJSONString(powerChangeRedisList), 3600 * dispatchConfig.getRideTime() + 1200);
                        LogUtil.info("调度定时任务添加缓存：" + machineNO + ";" + powerChangeRedisList.toString() + ";" + (3600 * dispatchConfig.getRideTime() + 1200));
                    } else {
                        /**删除缓存*/
                        redisService.del(RedisConstant.REDIS_TER_DISPATCH_CHANGE_RIDE + machineNO);
                        LogUtil.info("调度定时任务删除缓存：" + machineNO + ";");
                        /**二级缓存*/
                        redisService.del(RedisConstant.REDIS_TER_BIKE_DISPATCH_CHANGE_RIDE_MAP, machineNO);
                        LogUtil.info("调度定时任务删除二级缓存：" + machineNO + ";");
                    }
                } else {
                    /**删除缓存*/
                    redisService.del(RedisConstant.REDIS_TER_DISPATCH_CHANGE_RIDE + machineNO);
                    LogUtil.info("调度定时任务删除不存在调度缓存：" + machineNO + ";");
                    redisService.del(RedisConstant.REDIS_TER_BIKE_DISPATCH_CHANGE_RIDE_MAP, machineNO);
                    LogUtil.info("调度定时任务删除不存在二级缓存：" + machineNO + ";");
                }
            }
        }

        /** 查询当前换电工单的记录 */
        Map<String, String> machineBatteryMap = redisService.getAll(RedisConstant.REDIS_TER_BIKE_BATTERY_CHANGE_RIDE_MAP);
        if (machineBatteryMap.size() > 0) {
            String newTime = DateTimeUtil.getNowTime();
            for (String machineNO : machineBatteryMap.keySet()) {

                /**判断是否存在*/
                String redis = redisService.get(RedisConstant.REDIS_TER_BATTERY_CHANGE_RIDE + machineNO);
                if (redis != null) {

                    AccountConfig accountConfig = dataService.getAccountConfig(dataService.getAccountId(machineNO));
                    List<PowerChangeRedis> powerChangeRedisList = new LinkedList<>();
                    try {
                        powerChangeRedisList = JSON.parseArray(redis, PowerChangeRedis.class);
                    } catch (JSONException e) {
                        redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE_RIDE + machineNO);
                    }


                    if (powerChangeRedisList != null && powerChangeRedisList.size() > 0) {
                        /**循环遍历多个审核中记录*/
                        Iterator<PowerChangeRedis> it = powerChangeRedisList.iterator();
                        while (it.hasNext()) {
                            PowerChangeRedis powerChangeRedis = it.next();

                            if (DateTimeUtil.getTime(powerChangeRedis.getTime(), newTime) > powerChangeRedis.getRideTime() * 3600) {
                                WorkOrder workOrderDB = workOrderService.getByWorkOrderId(powerChangeRedis.getWorkOrderId());
                                /**判断存储是否是工单*/
                                if (workOrderDB != null) {
                                    WorkOrder workOrder = new WorkOrder();
                                    workOrder.setWorkOrderId(powerChangeRedis.getWorkOrderId());
                                    workOrder.setState(WorkOrderConstant.state_WC);
                                    workOrder.setIsValid(0);
                                    workOrder.setRemark(workOrderDB.getRemark() + WorkOrderConstant.sys_rideTime_Valid);
                                    workOrderService.update(workOrder);
                                }

                                PowerChangeLog powerChangeLog = powerChangeLogService.getPowerChangeLogId(powerChangeRedis.getPowerChangeId());

                                powerChangeLogService.update(powerChangeRedis.getPowerChangeId(), null, WorkOrderConstant.isValid, powerChangeLog.getRemark() + WorkOrderConstant.sys_rideTime_Valid, newTime);

                                /**审核后删除*/
                                it.remove();
                            }
                        }
                    }

                    /**判断是否为空，删除缓存*/
                    if (powerChangeRedisList != null && powerChangeRedisList.size() > 0) {
                        redisService.add(RedisConstant.REDIS_TER_BATTERY_CHANGE_RIDE + machineNO, JSONObject.toJSONString(powerChangeRedisList), 3600 * accountConfig.getRideTime() + 1200);
                    } else {
                        /**删除缓存*/
                        redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE_RIDE + machineNO);
                        /**二级缓存*/
                        redisService.del(RedisConstant.REDIS_TER_BIKE_BATTERY_CHANGE_RIDE_MAP, machineNO);
                    }
                } else {
                    /**二级缓存*/
                    redisService.del(RedisConstant.REDIS_TER_BIKE_BATTERY_CHANGE_RIDE_MAP, machineNO);
                }
            }
        }

        long t2 = System.currentTimeMillis();
        LogUtil.info("判断换电工单，调度记录定时任务时间" + (t2 - t1) + "ms");
    }

    /***
     * 添加远程指令日志
     * @param machine
     * @param serNo
     * @param orderContent
     * @param remark
     */
    public void setOrderLog(Machine machine, String serNo, String orderContent, String remark) {
        LogUtil.info("[" + machine.getMachineNO() + "]" + remark);

        /**远程指令日志*/
        OrderLog orderLog = new OrderLog();
        orderLog.setMachineId(machine.getMachineId());
        orderLog.setMachineNo(machine.getMachineNO());
        orderLog.setUserCode(machine.getUserCode());
        orderLog.setOpType(0);
        orderLog.setOpId(0);
        orderLog.setAccountUserId(0);
        orderLog.setOpTime(DateTimeUtil.getNowTime());
        orderLog.setChannelType(0);
        orderLog.setBusinessType(1);
        orderLog.setOrderType(ControlTypeConstant.CONTROL_TYPE_CONTROL);
        orderLog.setOrderSerNo(serNo);
        orderLog.setOrderSource(8);
        orderLog.setOrderContent(orderContent);
        orderLog.setRemark(remark);
        orderLogService.insert(orderLog);
    }

}